package com.eras.shoes.ui

import android.Manifest
import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.bluetooth.le.ScanResult
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
import android.graphics.Paint
import android.os.Build
import android.os.Bundle
import android.os.CountDownTimer
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.TextView
import androidx.activity.ComponentActivity
import androidx.appcompat.widget.ListPopupWindow
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import com.eras.shoes.R
import com.eras.shoes.adapter.DeviceAdapter
import com.eras.shoes.contents.Api
import com.eras.shoes.contents.ApiResponse
import com.eras.shoes.contents.BindShoes
import com.eras.shoes.contents.BleBean
import com.eras.shoes.contents.BleDataEx
import com.eras.shoes.contents.BluetoothDeviceWithRssi
import com.eras.shoes.contents.CheckNetUse
import com.eras.shoes.contents.DeviceData.*
import com.eras.shoes.contents.DictData
import com.eras.shoes.contents.DictItem
import com.eras.shoes.contents.Global
import com.eras.shoes.contents.MessageCallBack
import com.eras.shoes.contents.MessageEvent
import com.eras.shoes.contents.ProductSnPrefixCheck
import com.eras.shoes.contents.SizeConfig
import com.eras.shoes.contents.UserConfigBean
import com.eras.shoes.databinding.LayoutMainBoardBinding
import com.eras.shoes.db.MacBlacklistManager
import com.eras.shoes.utils.BluetoothController
import com.eras.shoes.utils.ByteUtils
import com.eras.shoes.utils.DimensUtil
import com.eras.shoes.utils.FastClick
import com.eras.shoes.utils.OkHttpUtils
import com.eras.shoes.utils.ToastUtils
import com.eras.shoes.view.RxDialogSureCancel
import com.eras.shoes.view.popupdialog.PopupSheet
import com.eras.shoes.view.popupdialog.PopupSheetCallback
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.google.zxing.integration.android.IntentIntegrator
import com.google.zxing.integration.android.IntentResult
import com.maning.mlkitscanner.scan.MNScanManager
import okhttp3.Request
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject
import java.io.IOException
import java.text.MessageFormat
import java.util.Arrays
import java.util.Objects


class MainBoardActivity  : ComponentActivity(), View.OnClickListener {
    private val TAG = "MainBoardActivity"
    private var INSOLE_NAME: String = "INSOLE_DEVICE"
    private var INSOLE_NAME_CN: String = "康复鞋-"
    private val PERMISSIONS_REQUEST_CODE = 101
    private val REQUIRED_PERMISSIONS = arrayOf(
        Manifest.permission.BLUETOOTH,
        Manifest.permission.BLUETOOTH_ADMIN,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
//    private var shoesName: String = ""//蓝牙鞋
    private var serialNumber: String = ""//序列号
    private val sharedPref by lazy {
        getSharedPreferences("login_prefs", Context.MODE_PRIVATE)
    }
    private var broadcastReceiver: BtTemperatureReceiver? = null
    // 蓝牙核心组件
    private val foundDevices = mutableListOf<BleBean>()
    private var connectDevice: BleBean = BleBean() //连接成功的设备

    private val deviceList = mutableListOf<ScanResult>()
    private lateinit var manager: MacBlacklistManager

    private val bluetoothController = BluetoothController.getInstance()
    private var currentRssiThreshold = -40 // 默认功率阈值
    private var count: Int = 5;//比对重试次数
    private var codeType: Int = 0;//判断扫码

    private var timer: CountDownTimer? = null

    private lateinit var binding: LayoutMainBoardBinding
    // 添加设备超时管理
    private val deviceTimeoutMap = mutableMapOf<String, Long>() // 记录设备最后出现时间
    private val DEVICE_TIMEOUT = 10000L // 12秒超时（考虑间歇扫描）
    private val cleanupHandler = Handler(Looper.getMainLooper())
    private val cleanupRunnable = object : Runnable {
        override fun run() {
            Log.e("Bluetooth", " removeTimeoutDevices")
            removeTimeoutDevices()
            cleanupHandler.postDelayed(this, 2000) // 每2秒检查一次
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // 强制竖屏
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        binding = LayoutMainBoardBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.tvMainBoardBack.setOnClickListener(this)
        binding.tvMainRefresh.setOnClickListener(this)
        binding.tvBoardRssiIdFour.setOnClickListener(this)
        binding.tvBoardRssiIdFive.setOnClickListener(this)
        binding.tvBoardRssiIdSix.setOnClickListener(this)
        binding.tvBoardRssiIdSeven.setOnClickListener(this)

        binding.btnScanCode.setOnClickListener(this)
        binding.btnWrite.setOnClickListener(this)
        binding.btnSave.setOnClickListener(this)
        binding.btnNext.setOnClickListener(this)

//        binding.btnNetIsUse.setOnClickListener(this)
//        binding.tvWriteShoesType.setOnClickListener(this)
//        binding.tvWriteSerialType.setOnClickListener(this)
//        binding.tvWriteShoesColor.setOnClickListener(this)
//        binding.tvWriteShoesSize.setOnClickListener(this)
        binding.tvWriteFootTypeLeft.setOnClickListener(this)
        binding.tvWriteFootTypeRight.setOnClickListener(this)

        binding.tvNetIsUseResult.setOnClickListener(this)
        binding.btnPutInComparison.setOnClickListener(this)

        binding.llWriteCompany.setOnClickListener(this)
        binding.llWriteWord.setOnClickListener(this)
        binding.llWriteShoesType.setOnClickListener(this)
        binding.llWriteSerialType.setOnClickListener(this)
        binding.llWriteSpecification.setOnClickListener(this)
        binding.llWriteShoesSize.setOnClickListener(this)
        binding.llWriteShoesColor.setOnClickListener(this)


        manager = MacBlacklistManager(this@MainBoardActivity)
        getDate()

        binding.btnScanCode.setBackgroundResource(R.drawable.bg_grey_btn)
        binding.btnScanCode.isEnabled = false
        binding.btnWrite.setBackgroundResource(R.drawable.bg_grey_btn)
        binding.btnWrite.isEnabled = false
//        binding.tvWriteFootType.setBackgroundResource(R.drawable.bg_grey_btn)
//        binding.tvWriteFootType.isEnabled = false
        binding.btnPutInComparison.setBackgroundResource(R.drawable.bg_grey_btn)
        binding.btnPutInComparison.isEnabled = false
        binding.btnSave.setBackgroundResource(R.drawable.bg_grey_btn)
        binding.btnSave.isEnabled = false
        binding.btnNext.setBackgroundResource(R.drawable.bg_grey_btn)
        binding.btnNext.isEnabled = false


        val savedUsername = sharedPref.getString("username", "")
        binding.tvMainBoardBack.setText(savedUsername)

        checkPermissions()

        binding.rvMainBoardBt.apply {
            layoutManager = LinearLayoutManager(this@MainBoardActivity)
            adapter = this@MainBoardActivity.adapter
            addItemDecoration(DividerItemDecoration(this@MainBoardActivity, LinearLayoutManager.VERTICAL))
        }
        bluetoothController.initBle(this)
        // 检查权限
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(REQUIRED_PERMISSIONS, PERMISSIONS_REQUEST_CODE)
        } else {
            initBtState()
        }

    }

    override fun onStart() {
        super.onStart()
//        getDevice()
    }

    /**
     * 初始化蓝牙状态广播监听
     */
    private fun initBtState() {
        if (bluetoothController.isBleOpen) {
            bluetoothController.startScanBle()
        } else {
            bluetoothController.initBle(this)
        }
    }


    // 在Activity中初始化适配器
    @SuppressLint("MissingPermission")
    private val adapter = DeviceAdapter { device ->
        connectToDevice(device)
    }
    @SuppressLint("MissingPermission", "NotifyDataSetChanged")
    private fun connectToDevice(device: BleBean) {
        if(Global.connectState == 1) {
            ToastUtils().show(this@MainBoardActivity, "有设备正在连接中...")
            return
        }
        if (BluetoothController.macAddress == null) {
            Global.connectType = 0
            device.connectState = 0
            Global.address = device.address
            adapter.notifyDataSetChanged()
            bluetoothController.connect(device.address)
            return
        }
        if (BluetoothController.macAddress != null && BluetoothController.macAddress.equals(device.address)) {
            ToastUtils().show(this@MainBoardActivity, "该设备已连接")
            return
        }
        if (BluetoothController.macAddress != null) {
            bluetoothController.closeBuletooth(BluetoothController.macAddress)
            binding.tvWriteResult.text = ""
            BleBean(device.name, device.address, 0)
            Global.connectType = 0
            device.connectState = 0
            Global.address = device.address
            adapter.notifyDataSetChanged()
            bluetoothController.connect(device.address)
        }
        Log.e("Bluetooth", "正在连接: ${device.name}")
    }

    override fun onBackPressed() {
        super.onBackPressed()
        disConnect()
        finish()
    }


    @SuppressLint("MissingPermission")
    override fun onClick(p0: View?) {

        var dictLists: List<DictItem>
        when (p0?.id){
            R.id.tv_main_board_back -> {
                disConnect()
                finish()
            }
            R.id.tv_main_refresh -> {
                if (FastClick.isFastClick()) {
                    ToastUtils().show(this@MainBoardActivity, "请不要连续多次点击")
                    return
                }
                // 清空超时记录，强制刷新
                deviceTimeoutMap.clear()
                foundDevices.clear()
                deviceList.clear()
//                adapter.submitList(emptyList())
                if (BluetoothController.macAddress != null){
                    foundDevices.add(connectDevice)
                    // 更新当前连接设备的超时时间
                    deviceTimeoutMap[connectDevice.address] = System.currentTimeMillis()
                }
                adapter.submitList(foundDevices.toList())
                bluetoothController.startScanBle()
            }
            R.id.tv_board_rssi_id_four -> {
                reSetRissbg("-40")
                binding.tvBoardRssiIdFour.setBackgroundResource(R.drawable.bg_orange_btn)
                binding.tvBoardRssiIdFour.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))
//                val arrayBlueRssiId: Array<String> = resources.getStringArray(R.array.blue_rssi_id)
//                selectBlueRssiId(binding.tvBoardRssiId, arrayBlueRssiId)
            }
            R.id.tv_board_rssi_id_five -> {
                reSetRissbg("-50")
                binding.tvBoardRssiIdFive.setBackgroundResource(R.drawable.bg_orange_btn)
                binding.tvBoardRssiIdFive.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))
            }
            R.id.tv_board_rssi_id_six -> {
                reSetRissbg("-60")
                binding.tvBoardRssiIdSix.setBackgroundResource(R.drawable.bg_orange_btn)
                binding.tvBoardRssiIdSix.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))
            }
            R.id.tv_board_rssi_id_seven -> {
                reSetRissbg("-70")
                binding.tvBoardRssiIdSeven.setBackgroundResource(R.drawable.bg_orange_btn)
                binding.tvBoardRssiIdSeven.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))
            }
            R.id.btn_scan_code -> {
                if (FastClick.isFastClick()) {
                    ToastUtils().show(this@MainBoardActivity, "请不要连续多次点击")
                    return
                }
                codeType = 0
                // 扫描二维码
//                IntentIntegrator(this@MainBoardActivity)
//                    .setCaptureActivity(PortraitCaptureActivity::class.java)
//                    .initiateScan()
                MNScanManager.startScan(this) { resultCode, data ->
                    // 创建一个新的Intent或修改现有的Intent来包含codeType
                    val modifiedData = data ?: Intent()
                    modifiedData.putExtra("CODE_TYPE", codeType)
                    handlerResult(resultCode, modifiedData)
                }
            }
//            R.id.ll_write_company -> {//公司
//                dictLists = getItems("COMPANY")
//                selectDate(binding.tvWriteCompanyValue, dictLists, 0)
//            }
//
//            R.id.ll_write_shoes_type -> {//产品
//                dictLists = getItems("FEATURE_WORDS")
//                selectDate(binding.tvWriteShoesTypeValue, dictLists, 2)
//            }
//            R.id.ll_write_word -> {//核心词
//                dictLists = getItems("CORE_WORDS")
//                selectDate(binding.tvWriteWordValue, dictLists, 1)
//            }
//            R.id.ll_write_serial_type -> {//款式
//                dictLists = getItems("MODEL_CODE")
//                selectDate(binding.tvWriteSerialTypeValue, dictLists, 3)
//            }
//            R.id.ll_write_specification -> {//规格
//                dictLists = getItems("SPECIFICATION_CODE")
//                selectDate(binding.tvWriteSpecificationValue, dictLists, 6)
//            }
//            R.id.ll_write_shoes_color -> {//颜色
//                dictLists = getItems("COLOR")
//                selectDate(binding.tvWriteShoesColorValue, dictLists, 4)
//            }
//            R.id.ll_write_shoes_size -> {//尺码
//                if (Global.shoesConfig.equals("")) {
//                    ToastUtils().show(this@MainBoardActivity, "请先选择产品类型")
//                    return
//                }
//                val toJsonObj = JSONObject(Global.shoesConfig)
//                val sizeArrays: JSONArray = toJsonObj.getJSONArray("size")
//                val sizes = sizeList(sizeArrays.toString())
//                selectSizeDate(binding.tvWriteShoesSizeValue, sizes, 5)
//            }
//            R.id.tv_write_foot_type_left -> {//左脚
//                reSetFootType()
//                binding.tvWriteFootTypeLeft.setBackgroundResource(R.drawable.bg_orange_btn)
//                binding.tvWriteFootTypeLeft.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))
//                Global.footCode = "Z"
//                Global.footName = "左脚"
//                Global.footConfig = ""
//                val message = Message()
//                message.arg1 = 2
//                handler.sendMessage(message)
//            }
//            R.id.tv_write_foot_type_right -> {//右脚
//                reSetFootType()
//                binding.tvWriteFootTypeRight.setBackgroundResource(R.drawable.bg_orange_btn)
//                binding.tvWriteFootTypeRight.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))
//                Global.footCode = "Y"
//                Global.footName = "右脚"
//                Global.footConfig = ""
//                val message = Message()
//                message.arg1 = 2
//                handler.sendMessage(message)
//            }
            R.id.btn_net_is_use -> {
//                if (!checkDate()) {
//                    return
//                }
//                binding.progressBarNet.visibility = View.VISIBLE
//                binding.tvNetIsUseResult.text = ""
//                CheckNetIsUse(
//                    BluetoothController.macAddress,
//                    binding.tvWriteSerialNumberResult.text.toString()
//                )
            }
            R.id.btn_put_in_comparison -> {
                if (FastClick.isFastClick()) {
                    ToastUtils().show(this@MainBoardActivity, "请不要连续多次点击")
                    return
                }
                codeType = 1

                MNScanManager.startScan(this) { resultCode, data ->
                    // 创建一个新的Intent或修改现有的Intent来包含codeType
                    val modifiedData = data ?: Intent()
                    modifiedData.putExtra("CODE_TYPE", codeType)
                    handlerResult(resultCode, modifiedData)
                }
                // 扫描二维码
//                IntentIntegrator(this@MainBoardActivity)
//                    .setCaptureActivity(PortraitCaptureActivity::class.java)
//                    .initiateScan()
//                binding.tvPutinComparisonResult.text = ""
//                if (!checkDate()) {
//                    return
//                }
//                binding.tvPutinComparisonResult.text = "正在发送0x8D指令..."
                //测试获取mac地址，0x19
//                timer?.cancel()
//                timer = object : CountDownTimer(3000, 500) {
//                    override fun onTick(millisUntilFinished: Long) {
////                        val cmdCod: Byte = 0x8D.toByte()
//                        val cmdCod: Byte = 0x18.toByte()
//                        bluetoothController.writeData(BluetoothController.macAddress, cmdCod, "")
//                    }
//                    override fun onFinish() {
//                        binding.tvPutinComparisonResult.setText("完成整机测试失败，请重试")
//                    }
//                }.start()


//                binding.tvPutinComparisonResult.setText("正在获取序列号...")
//                timer = object : CountDownTimer(3000, 500) {
//                    override fun onTick(millisUntilFinished: Long) {
//                        val cmdCod: Byte = 0x1F.toByte()
//                        bluetoothController.writeData(BluetoothController.macAddress, cmdCod, "")
//                    }
//                    override fun onFinish() {
//                        binding.tvPutinComparisonResult.setText("获取序列号失败")
//                    }
//                }.start()

//                Global.addressCheck = BluetoothController.macAddress
//                Global.address = null
//                foundDevices.clear()
//                deviceList.clear()
//                adapter.submitList(emptyList())
//                if (BluetoothController.macAddress != null) {
//                    bluetoothController.closeBuletooth(BluetoothController.macAddress)
//                }
//                bluetoothController.startScanBle()

            }
            R.id.btn_write -> {//serialNumber
                if (FastClick.isFastClick()) {
                    ToastUtils().show(this@MainBoardActivity, "请不要连续多次点击")
                    return
                }
                if (!checkDate()) {
                    return
                }
                isnetUsed()
//                bindShoes(BluetoothController.macAddress, binding.tvPutinComparisonResult.text.toString())
//                WriteSN()
//                onWriteSerialNumber(binding.tvWriteSerialNumberResult.text.toString())
            }
            R.id.btn_save -> {
                if (FastClick.isFastClick()) {
                    ToastUtils().show(this@MainBoardActivity, "请不要连续多次点击")
                    return
                }

                saveDate()
//                reSetValue()
//                disConnect()
//                bluetoothController.startScanBle()
//                if (!checkDate()) {
//                    return
//                }
//                binding.progressBarSave.visibility = View.VISIBLE
//                saveCode(
//                    BluetoothController.macAddress,
//                    binding.tvWriteSerialNumberResult.text.toString()
//                )
            }
            R.id.btn_next -> {
                if (FastClick.isFastClick()) {
                    ToastUtils().show(this@MainBoardActivity, "请不要连续多次点击")
                    return
                }
                bindShoes(BluetoothController.macAddress, binding.tvPutinComparisonResult.text.toString())
//                binding.tvNextResult.setText("正在完成产测...")
//                val cmdCod: Byte = 0x8D.toByte()
////                bluetoothController.writeData(BluetoothController.macAddress, cmdCod, "")
//                timer = object : CountDownTimer(3000, 500) {
//                    override fun onTick(millisUntilFinished: Long) {
//                        val cmdCod: Byte = 0x8D.toByte()
//                        bluetoothController.writeData(BluetoothController.macAddress, cmdCod, "")
//                    }
//                    override fun onFinish() {
//                        binding.tvNextResult.setText("完成产测失败")
//                    }
//                }.start()
            }

        }
    }

    private fun handlerResult(resultCode: Int, data: Intent?) {
        if (data == null) {
            return
        }
        when (resultCode) {
            MNScanManager.RESULT_SUCCESS -> {
                val results = data.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
                // 从 Intent 中获取 codeType，如果没有则使用默认值 0
                val codeType = data.getIntExtra("CODE_TYPE", 0)
                if(results != null){
                    val resultStr = StringBuilder()
                    resultStr.clear()
                    var i = 0
                    while (i < results.size) {
                        resultStr.append(results[i])
                        i++
                    }
                    if (codeType == 0) {
                        if (resultStr.length != 9) {
                            ToastUtils().show(this@MainBoardActivity, "序列号不是9位")
                            return
                        }
                        serialNumber = resultStr.toString()//YK23BG002
//                serialNumber = "YK23BG003"
//                binding.tvSerialNumber.text = qrCodeContent
                        Log.e("MainBoardActivity", "qrCodeContent="+resultStr)
                        Log.e("MainBoardActivity", "qrCodeContentSize="+resultStr.length)
                        binding.btnWrite.setBackgroundResource(R.drawable.bg_orange_btn)
                        binding.btnWrite.isEnabled = true
                        if (!serialNumber.equals("")) {
                            val message = Message()
                            message.obj = serialNumber
                            message.arg1 = 2
                            handler.sendMessage(message)
                        }
                    } else if (codeType == 1) {
                        binding.tvPutinComparisonResult.text = resultStr
                        binding.btnScanCode.setBackgroundResource(R.drawable.bg_orange_btn)
                        binding.btnScanCode.isEnabled = true
                    }

                }

            }

            MNScanManager.RESULT_FAIL -> {
                val resultError = data.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
            }
            else -> {}
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        val result: IntentResult? = IntentIntegrator.parseActivityResult(requestCode, resultCode, data)
        if (result != null) {
            if (result.contents != null) {
                // 扫描结果，result.contents是二维码内容
                val qrCodeContent = result.contents
                if (codeType == 0) {
                    if (qrCodeContent.length != 9) {
                        ToastUtils().show(this@MainBoardActivity, "序列号不是9位")
                        return
                    }
                    serialNumber = qrCodeContent//YK23BG002
//                serialNumber = "YK23BG003"
//                binding.tvSerialNumber.text = qrCodeContent
                    Log.e("MainBoardActivity", "qrCodeContent="+qrCodeContent)
                    Log.e("MainBoardActivity", "qrCodeContentSize="+qrCodeContent.length)
                    binding.btnWrite.setBackgroundResource(R.drawable.bg_orange_btn)
                    binding.btnWrite.isEnabled = true
                    if (!serialNumber.equals("")) {
                        val message = Message()
                        message.obj = serialNumber
                        message.arg1 = 2
                        handler.sendMessage(message)
                    }
                } else if (codeType == 1) {
                    binding.tvPutinComparisonResult.text = qrCodeContent
                    binding.btnScanCode.setBackgroundResource(R.drawable.bg_orange_btn)
                    binding.btnScanCode.isEnabled = true
                }

                // 这里可以添加HTTP请求获取数据的代码
                // 例如使用kotlinx.coroutines或者其他网络库发起请求
            } else {
                // 扫描失败
            }
        } else {
            super.onActivityResult(requestCode, resultCode, data)
        }
    }

    override fun onResume() {
        super.onResume()
        // 启动设备清理任务
        cleanupHandler.postDelayed(cleanupRunnable, 2000)
//        bluetoothController.startScanBle()
        if (!EventBus.getDefault().isRegistered(this)) { //加上判断
            EventBus.getDefault().register(this)
        }
        broadcastReceiver = BtTemperatureReceiver()
        val intentFilter = IntentFilter()
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED)
        registerReceiver(broadcastReceiver, intentFilter)
    }

    override fun onPause() {
        super.onPause()
        // 停止设备清理任务
        cleanupHandler.removeCallbacks(cleanupRunnable)
        bluetoothController.stopScanBle()
        EventBus.getDefault().unregister(this)
        unregisterReceiver(broadcastReceiver) //注销广播接收器
    }

    private fun updateDeviceList(device: BluetoothDeviceWithRssi) {
        val existingIndex = foundDevices.indexOfFirst {
            it.address == device.bean.address
        }
        if (existingIndex >= 0) {
            foundDevices[existingIndex] = device.bean
        } else {
            foundDevices.add(device.bean)
        }
        foundDevices.sortByDescending { device.bean.rssi } // 按value降序排序
        adapter.submitList(foundDevices.toList())
    }

    // 处理主线程事件（默认模式）
    @SuppressLint("NotifyDataSetChanged")
    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event: MessageEvent<*>) {
        var bleBeans: BleBean
        when (event.getAction()) {
            MessageEvent.ACTION_GATT_CONNECTED -> {
                Global.connectState = 2
                Global.isConnected = true
                bleBeans = event.data as BleBean
                Global.connectType = 1
                for (i in 0 until foundDevices.size) {
                    val bleBean: BleBean = foundDevices.get(i)
                    if (bleBean.address.equals(bleBeans.address)) {
                        bleBean.connectState = 1
                        bleBeans = bleBean
                    }
                }
                adapter.notifyDataSetChanged()
                connectSuccess(bleBeans)
            }

            MessageEvent.ACTION_GATT_DISCONNECTED -> {
                Global.connectState = 0
                val address = event.data as String
                Global.isConnected = false
                Global.connectType = -1
                Global.address = null
                BluetoothController.macAddress = null
                reSetValue()
                for (i in 0 until foundDevices.size) {
                    val bleBean: BleBean = foundDevices.get(i)
                    if (bleBean.address.equals(address)) {
                        bleBean.connectState = -1
                    }
                }
                adapter.notifyDataSetChanged()
            }

            MessageEvent.BLE_SCAN_RESULT -> {
                // 添加蓝牙
                addBluetooth(event.data as ScanResult)
            }
            MessageEvent.BLE_MAC_SCAN_RESULT -> {
                runOnUiThread{
                    // 添加蓝牙
                    val writeSerial: String = event.data.toString()
                    if (writeSerial.equals(serialNumber)) {
                        Log.i("MainBoardActivity", "产品序列号校验通过")
                        binding.tvWriteResult.setText("序列号验证成功")
//                        binding.ivPutinSuccess.visibility = View.VISIBLE
                        saveDate()
//                        ToastUtils().show(this@MainBoardActivity, "产品序列号校验通过")
                    } else {
                        binding.tvWriteResult.setText("序列号验证失败")
//                        binding.progressBarWite.visibility = View.GONE
//                        binding.tvPutinComparisonResult.text = "序列号校验失败，没有写入成功"
//                        ToastUtils().show(this@MainBoardActivity, "产品序列号校验失败，没有写入成功")
                    }
                }

            }

            MessageEvent.EVENT_DEVICE_COLL_BACK -> {
                Log.i("MainBoardActivity", "EVENT_DEVICE_COLL_BACK :" + event.data)
                val strRecvTxt = event.data.toString()
                if (strRecvTxt.length > 1) {
                    val gson: Gson = Gson()
                    val messageCallBack: MessageCallBack =
                        gson.fromJson(strRecvTxt, MessageCallBack::class.java)
                    Log.i("MainBoardActivity", "messageCallBack_Cmd :" + messageCallBack.cmd)
                    if (messageCallBack.cmd.equals("8c")) {
                        Log.i("MainBoardActivity", "接收8C指令回调")
                        timer?.cancel()
                        binding.tvWriteResult.setText("收到8C指令回调")
                        binding.tvWriteResult.setText("正在获取序列号...")
                        timer = object : CountDownTimer(3000, 500) {
                            override fun onTick(millisUntilFinished: Long) {
                                val cmdCod: Byte = 0x1F.toByte()
                                bluetoothController.writeData(BluetoothController.macAddress, cmdCod, "")
                            }
                            override fun onFinish() {
                                binding.tvWriteResult.setText("获取序列号失败")
                            }
                        }.start()


//                        val dataBack: String = messageCallBack.msg
//                        val content0: String = dataBack.toString().substring(8, 10)//命令字
////                        val content1: String = dataBack.toString().substring(46, 48)//应答码
//                        val content2: String = dataBack.toString().substring(46, 90)//序列号
//                        val dataBackSn: String = ByteUtils.hexToString(content2)
//                        Log.i("MainBoardActivity", "接收8C指令回调dataBackSn="+dataBackSn)
//                        binding.tvWriteResult.setText(dataBackSn)
//                        if (binding.tvWriteSerialNumberResult.text.toString().equals(dataBackSn)) {
//                            binding.tvWriteResult.text = "SN比对成功"
//                            saveDate()//完成写入SN比对，自动保存当前序列号
//                        } else {
//                            if (count > 0) {
//                                count--
//                                binding.tvWriteResult.text = "SN比对失败，正在重新写入"
//                                timer = object : CountDownTimer(3000, 500) {
//                                    override fun onTick(millisUntilFinished: Long) {
//                                        val cmdCod: Byte = 0x8C.toByte()
//                                        bluetoothController.writeData(BluetoothController.macAddress, cmdCod, binding.tvWriteSerialNumberResult.text.toString())
//                                    }
//                                    override fun onFinish() {
//                                        binding.tvWriteResult.setText("SN写入失败")
//                                    }
//                                }.start()
//                            } else {
//                                count = 5
//                                binding.tvWriteResult.text = "SN比对失败"
//                            }
//                        }
//                        binding.tvWriteResult.setText("正在发送8D指令...")
//                        bluetoothController.writeData(BluetoothController.macAddress, cmdCod, "")//binding.tvWriteSerialNumberResult.text.toString()
//                        val message = Message()
//                        message.obj = messageCallBack.msg
//                        message.arg1 = 1
//                        handler.sendMessage(message)
//                        saveDate()//完成写入SN，自动保存当前序列号
                    } else if (messageCallBack.cmd.equals("8d")) {
                        Log.i("MainBoardActivity", "接收8D指令回调")
                        binding.tvNextResult.text = "产测已完成"
                        val dataBack: String = messageCallBack.msg
                        Log.i("MainBoardActivity", "EVENT_DEVICE_COLL_BACK :" + dataBack)
                        timer?.cancel()
                        //  完成产测后 先自动保存鞋垫序列号  再保存主板序列号
                        bindShoes(BluetoothController.macAddress, binding.tvPutinComparisonResult.text.toString())
//                        binding.tvPutinComparisonResult.text = "收到8D指令回调"
//                        binding.tvPutinComparisonResult.text = "完成整机测试"
//                        saveDate()//完成整机测试自动保存当前序列号
//                        binding.btnSave.setBackgroundResource(R.drawable.bg_orange_btn)
//                        binding.btnSave.isEnabled = true
//                        binding.tvWriteResult.setText("正在上传序列号...")
//                        saveDate()
//                        val message = Message()
//                        message.obj = messageCallBack.msg
//                        message.arg1 = 1
//                        handler.sendMessage(message)
                    } else if (messageCallBack.cmd.equals("1f")) {
                        timer?.cancel()
                        val dataBack: String = messageCallBack.msg
                        Log.i("MainBoardActivity", "EVENT_DEVICE_COLL_BACK :" + dataBack)
                        val content0: String = dataBack.substring(8, 10)//命令字
                        val content1: String = dataBack.substring(46, 48)//应答码
                        val content2: String = dataBack.substring(48, 92)//序列号
                        val dataBackSn: String = ByteUtils.hexToString(content2)
                        Log.i("MainBoardActivity", "接收1F指令回调dataBackSn="+content1)
                        Log.i("MainBoardActivity", "接收1F指令回调dataBackSn="+content2)
                        Log.i("MainBoardActivity", "接收1F指令回调dataBackSn="+dataBackSn)
//                        binding.tvPutinComparisonResult.setText(dataBackSn)
                        binding.tvWriteResult.text = "dataBackSn"
                        if (binding.tvWriteSerialNumberResult.text.trim().toString().equals(dataBackSn.trim())) {
                            count = 5
                            binding.tvWriteResult.text = "SN比对成功"
//                            saveDate()//完成写入SN比对，自动保存当前序列号
//                            binding.btnNext.setBackgroundResource(R.drawable.bg_orange_btn)
//                            binding.btnNext.isEnabled = true

                            if (Global.shoesName.equals("康复鞋")) {
                                onWriteSHoesName("鞋-")
                            } else if (Global.shoesName.equals("足踝靴")) {
                                onWriteSHoesName("靴-")
                            }

                        } else {
                            if (count > 0) {
                                count--
                                binding.tvWriteResult.text = "SN比对失败，正在重新比对"
                                timer = object : CountDownTimer(3000, 500) {
                                    override fun onTick(millisUntilFinished: Long) {
                                        val cmdCod: Byte = 0x1F.toByte()
                                        bluetoothController.writeData(BluetoothController.macAddress, cmdCod, "")
                                    }
                                    override fun onFinish() {
                                        binding.tvWriteResult.setText("获取序列号失败")
                                    }
                                }.start()
                            } else {
                                count = 5
                                binding.tvWriteResult.text = "SN比对失败"
                            }

                        }

                    } else if (messageCallBack.cmd.equals("66")) {
                        val dataBack: String = messageCallBack.msg
//                        binding.tvWriteResult.setText(dataBack)
                        Log.i("MainBoardActivity", "dataBack=="+dataBack)
//                        val content0: String = dataBack.toString().substring(8, 10)
                        val content1: String = dataBack.toString().substring(46, 48)
//                        val content2: String = dataBack.toString().substring(48, 58)
//                        Log.i("MainBoardActivity", "接收指令回调content0=="+content0)
//                        Log.i("MainBoardActivity", "接收指令回调content1=="+content1)
//                        Log.i("MainBoardActivity", "接收指令回调content2=="+content2)
                        timer?.cancel()
//                        ByteUtils.hexToString(content2)
//                        binding.tvPutinComparisonResult.text = ByteUtils.hexToString(content2)

                        if(content1.equals("00")) {
                            count = 5
                            binding.tvWriteResult.text = "设备名称写入成功"
                            binding.btnNext.setBackgroundResource(R.drawable.bg_orange_btn)
                            binding.btnNext.isEnabled = true
                        } else {
                            if (count > 0) {
                                count--
                                binding.tvWriteResult.text = "写入设备名称失败，正在重新写入"
                                timer = object : CountDownTimer(3000, 500) {
                                    override fun onTick(millisUntilFinished: Long) {
//                                        val cmdCod: Byte = 0x66.toByte()
//                                        bluetoothController.writeData(BluetoothController.macAddress, cmdCod, "")
                                        if (Global.shoesName.equals("康复鞋")) {
                                            onWriteSHoesName("鞋-")
                                        } else if (Global.shoesName.equals("足踝靴")) {
                                            onWriteSHoesName("靴-")
                                        }
                                    }
                                    override fun onFinish() {
                                        binding.tvWriteResult.setText("写入设备名称失败")
                                    }
                                }.start()
                            } else {
                                count = 5
                                binding.tvWriteResult.text = "写入设备名称失败"
                            }
                        }


                    } else if (messageCallBack.cmd.equals("18")) {
                        val dataBack: String = messageCallBack.msg
                        val content0: String = dataBack.toString().substring(8, 10)
                        val content1: String = dataBack.toString().substring(46, 48)
                        val content2: String = dataBack.toString().substring(48, 58)
                        Log.i("MainBoardActivity", "接收指令回调content0=="+content0)
                        Log.i("MainBoardActivity", "接收指令回调content1=="+content1)
                        Log.i("MainBoardActivity", "接收指令回调content2=="+content2)
                        timer?.cancel()
//                        ByteUtils.hexToString(content2)
//                        binding.tvPutinComparisonResult.text = ByteUtils.hexToString(content2)

                    }
                }
            }
        }
    }

    @SuppressLint("MissingPermission")
    private fun addBluetooth(result: ScanResult) {
        if (manager.isBlacklisted(result.device.address)) {
            return
        }
        if (currentRssiThreshold >= result.rssi) {
            return
        }

        val type = if (result.device.name.contains("LEFT") || result.device.name.contains("左")) {
            0
        } else if (result.device.name.contains("RIGHT") || result.device.name.contains("右")) {
            1
        } else {
            2
        }

        if (type ==2){
            return
        }
        Log.i(TAG, "onScanResult: type$type")

        // 更新设备最后出现时间
        deviceTimeoutMap[result.device.address] = System.currentTimeMillis()
//        if (Global.footName.equals("左脚")) {
//            if(!result.device.name.contains("左")) {
//                return
//            }
//        }
//        if (Global.footName.equals("右脚")) {
//            if(!result.device.name.contains("右")) {
//                return
//            }
//        }
        this.runOnUiThread(Runnable {
            // 先移除超时设备
            removeTimeoutDevices()

            if (!deviceList.any { it.device.address == result.device.address }) {
                deviceList.add(result)
                val bytes = result.scanRecord!!.bytes
                var serial = BleDataEx.getStringValue(bytes, 17, 10)
                if (serial != null) {
                    // 如果包含"00000000"则丢弃
                    if (serial.contains("00000000")) {
                        serial = "00000000"
                    } else {
                        // 找到第一个非字母数字字符的位置
                        var invalidCharIndex = -1
                        for (i in 0 until serial.length) {
                            val c = serial[i]
                            if (!Character.isLetterOrDigit(c)) {
                                invalidCharIndex = i
                                break
                            }
                        }

                        // 如果有乱码，截取有效部分
                        if (invalidCharIndex != -1) {
                            serial =
                                serial.substring(0, invalidCharIndex)
                        }
                    }
                }

                val bean = BleBean(result.device.name, result.device.address, result.rssi, serial ,type)
                if (Global.addressCheck.equals(result.device.address)) {
                    connectToDevice(bean)
                }
                updateDeviceList(BluetoothDeviceWithRssi(bean, result.rssi))
            }
        })
    }
    @SuppressLint("MissingPermission")
    private fun connectSuccess(data: BleBean) {
        connectDevice = data
        this.runOnUiThread(Runnable {
            Log.i("MainBoardActivity", "connectSuccess="+data.toString())
            val name = data.name
//            shoesName = name
//            val address = data.address
//            BluetoothController.macAddress = address

//            binding.tvWriteFootType.setBackgroundResource(R.drawable.bg_orange_btn)
//            binding.tvWriteFootType.isEnabled = true

            when (data.type) {
                2 -> showType2Dialog()
                0 -> handleType0()
                1 -> handleType1()
                else -> Log.w(TAG, "Unknown device type: ${data.type}")
            }
            Log.e(TAG, "calibCheck:"+data.type+","+Global.footCode+","+productSnPrefix)
            // 有左右脚信息  上传对应的产品序列号前缀
            if(data.type == 0 || data.type ==1){
                checkwWriteCodeConfig(data.address,productSnPrefix )
                binding.tvWriteSerialNumberResult.text = companyCode+shoesCode+wordCode+serialCode+specificationCode+Global.footCode+sizeCode+colorCode+Global.colorConfig
            }
        })
    }

    private fun showType2Dialog() {
        RxDialogSureCancel(this@MainBoardActivity).apply {
            setSureListener {
                dismiss()
                disConnect() // 断开连接
                finish()    // 结束当前Activity，返回上一页
            }
            show()
        }
    }

    // 增加定标时校验连接的蓝牙信息  不一致提示 并且阻断当前页面，返回到主页面
    private fun showCalibCheckDialog(message: String) {
        RxDialogSureCancel(this@MainBoardActivity).apply {
            contentView.text = message
            setSureListener {
                dismiss()
//                disConnect() // 断开连接
//                finish()    // 结束当前Activity，返回上一页
            }
            show()
        }
    }

    private fun handleType0() {
        Global.footCode = "Z"
        updateProductSnPrefix()
        reSetFootType()
                binding.tvWriteFootTypeLeft.setBackgroundResource(R.drawable.bg_orange_btn)
                binding.tvWriteFootTypeLeft.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))

    }

    private fun handleType1() {
        Global.footCode = "Y"
        updateProductSnPrefix()
        reSetFootType()
        binding.tvWriteFootTypeRight.setBackgroundResource(R.drawable.bg_orange_btn)
        binding.tvWriteFootTypeRight.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))
    }

    private fun updateProductSnPrefix() {
        productSnPrefix = companyCode + shoesCode + wordCode + serialCode +
                specificationCode + Global.footCode + sizeCode +
                colorCode + Global.colorConfig
    }

    private fun checkwWriteCodeConfig(mac: String, productSnPrefix:String ) {
        val user = ProductSnPrefixCheck("", "")
        user.mac = mac
        user.productSnPrefix = productSnPrefix
        val data = Gson().toJson(user)
        OkHttpUtils.postJsonAsync(this@MainBoardActivity, Api.checkWriteCodeConfig, data, object : OkHttpUtils.DataCallBack {
            override fun requestFailure(request: Request, e: IOException) {
                Log.e("MainBoardActivity", "检验失败")
                showCalibCheckDialog("检验失败，请检查网络是否异常")
            }

            @Throws(Exception::class)
            override fun requestSuccess(result: String) {
                val toJsonObj = JSONObject(result)
                Log.e("MainBoardActivity", "检验返回"+toJsonObj)
                val code = toJsonObj.getInt("code")
                if (code == 0) {
                    val messages = toJsonObj["message"] as String
                    ToastUtils().show(this@MainBoardActivity, "检验成功：" + messages)
                    binding.btnPutInComparison.setBackgroundResource(R.drawable.bg_orange_btn)
                    binding.btnPutInComparison.isEnabled = true
                } else {
                    val messages = toJsonObj["message"] as String
//                    ToastUtils().show(this@MainBoardActivity, "检验失败：" + messages)
                    // 增加定标时校验连接的蓝牙信息  不一致提示 并且阻断当前页面，返回到主页面
                    showCalibCheckDialog(messages)
                }
            }
        })
    }


    @SuppressLint("MissingPermission")
    private fun onWriteSerialNumber(serNumber: String) {//EMXZXLY01Y4G0YK3254A096
        val cmdCod: Byte = 0x8C.toByte()//EMZHXLY1AYLG0YK3254A096
        Log.i("MainBoardActivity", "发送0X8C指令="+serNumber)//YK23BG002
        binding.tvWriteResult.setText("正在发送8C指令...")
//        val writeData =
//            bluetoothController.writeData(BluetoothController.macAddress, cmdCod, serNumber)
        // 60秒倒计时，间隔1秒
        timer?.cancel()
        timer = object : CountDownTimer(3000, 500) {
            override fun onTick(millisUntilFinished: Long) {
                bluetoothController.writeData(BluetoothController.macAddress, cmdCod, serNumber)
            }
            override fun onFinish() {
                binding.tvWriteResult.setText("SN写入失败")
            }
        }.start()
    }
    @SuppressLint("MissingPermission")
    private fun onWriteSHoesName(shoesName: String) {
        val cmdCod: Byte = 0x66.toByte()
        Log.i("MainBoardActivity", "发送0X66指令shoesName="+shoesName)
        binding.tvWriteResult.setText("正在发送0X66指令...")
        // 60秒倒计时，间隔1秒
        timer?.cancel()
        timer = object : CountDownTimer(3000, 500) {
            override fun onTick(millisUntilFinished: Long) {
                bluetoothController.writeData(BluetoothController.macAddress, cmdCod, shoesName)
            }
            override fun onFinish() {
                binding.tvWriteResult.setText("产品名称写入失败")
            }
        }.start()
    }

    @SuppressLint("HandlerLeak")
    var handler: Handler = object : Handler() {
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            val type = msg.arg1
            when (type) {
                1 -> {
                    binding.tvWriteResult.setText("正在获取序列号...")
                    timer = object : CountDownTimer(3000, 500) {
                        override fun onTick(millisUntilFinished: Long) {
                            val cmdCod: Byte = 0x1F.toByte()
                            bluetoothController.writeData(BluetoothController.macAddress, cmdCod, "")
                        }
                        override fun onFinish() {
                            binding.tvWriteResult.setText("获取序列号失败")
                        }
                    }.start()
//                    checkWrite()
                }
                2 -> {
                    setConfigDate(1)  //  0 代表  刚进去  无法知道选择左脚还是右脚 不显示类型    1  代表已经连接可以知晓左右脚
                    setUserConfig(companyCode,shoesCode,wordCode,serialCode,specificationCode,Global.footCode,colorCode,sizeCode,colorConfig)
                }
            }
        }
    }

    // 在onDestroy中取消注册
    @SuppressLint("MissingPermission")
    override fun onDestroy() {
        super.onDestroy()
        // 停止清理任务
        cleanupHandler.removeCallbacks(cleanupRunnable)
        deviceTimeoutMap.clear()
        bluetoothController.stopScanBle()
    }
    private fun checkPermissions() {
        val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            arrayOf(
                Manifest.permission.BLUETOOTH_SCAN,
                Manifest.permission.BLUETOOTH_CONNECT,
                Manifest.permission.ACCESS_FINE_LOCATION
            )
        } else {
            arrayOf(
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.BLUETOOTH,
                Manifest.permission.BLUETOOTH_ADMIN
            )
        }

        // 检查并请求缺失的权限
        val missingPermissions = permissions.filter {
            ContextCompat.checkSelfPermission(this, it) != PackageManager.PERMISSION_GRANTED
        }.toTypedArray()

        if (missingPermissions.isNotEmpty()) {
            requestPermissions(missingPermissions, PERMISSIONS_REQUEST_CODE)
        } else {
            initBtState()
        }
    }

    private fun selectBlueRssiId(view: TextView, arrays: Array<String>) {
        // 测量文本最大宽度
        var maxWidth = 0f
        var item: String = ""
        // 测量文本最大宽度
        val paint = Paint()
        for (i in 0 until arrays.size) {
            item = arrays.get(i)
            val width = paint.measureText(item)
            if (width > maxWidth) {
                maxWidth = width
            }
        }
        val popupSheet: PopupSheet
        val arrayList = Arrays.asList(*arrays)
        popupSheet =
            PopupSheet(this@MainBoardActivity, view, arrayList, object : PopupSheetCallback {
                override fun setupItemView(position: Int): View {
                    val itemV: View =
                        LayoutInflater.from(this@MainBoardActivity)
                            .inflate(R.layout.item_surgery_name, null)
                    val titleTV = itemV.findViewById<TextView>(R.id.tv_surgery_name)
                    titleTV.text = MessageFormat.format("{0}", arrayList[position])
                    return itemV
                }

                override fun itemClicked(popupWindow: ListPopupWindow, position: Int) {
                    popupWindow.dismiss()
                    view.text = arrayList[position].toString()
                    when (arrayList[position]) {
                        "-40dB" -> {
                            currentRssiThreshold = -40
                        }

                        "-50dB" -> {
                            currentRssiThreshold = -50
                        }

                        "-60dB" -> {
                            currentRssiThreshold = -60
                        }
                        "-70dB" -> {
                            currentRssiThreshold = -70
                        }
                    }
                    foundDevices.clear()
                    deviceList.clear()
                    adapter.submitList(emptyList())
                    bluetoothController.startScanBle()
                }
            }, DimensUtil.dp2px(this@MainBoardActivity, maxWidth+80F))
        popupSheet.show()
    }
    private fun getDevice() {
        OkHttpUtils.getAsyncToken(this@MainBoardActivity, Api.deviceList, true, object :
            OkHttpUtils.DataCallBack {
            override fun requestFailure(request: Request, e: IOException) {
            }

            @SuppressLint("SetTextI18n")
            @Throws(Exception::class)
            override fun requestSuccess(result: String) {
                val toJsonObj = JSONObject(result)
                Log.e("MainBoardActivity", "返回$toJsonObj")
                val code = toJsonObj.getInt("code")
                if (code == 0) {
                    val response = parseDeviceJson(result)
                    response.data.items.forEach { item ->
                        Log.d("MainBoardActivity", "名称:${item.deviceName} 编码:${item.deviceCode}")
                    }
                }
            }
        })

    }
    private fun sizeList(json: String): List<SizeConfig> {
        return Gson().fromJson(json, object : TypeToken<List<SizeConfig>>() {}.type)
    }

    fun parseDeviceJson(json: String): ApiResponse {
        return  Gson().fromJson(json, ApiResponse::class.java)
    }
    private fun selectDate(view: TextView, arrays: List<DictItem>, tag: Int) {
        // 测量文本最大宽度
        var maxWidth = 0f
        var item: String = ""
        // 测量文本最大宽度
        val paint = Paint()
        for (i in 0 until arrays.size) {
            item = arrays.get(i).ruleName
            val width = paint.measureText(item)
            if (width > maxWidth) {
                maxWidth = width
            }
        }
        val popupSheet: PopupSheet
        val showArrayList = arrays//Arrays.asList(/* ...a = */ *arrays)
        popupSheet =
            PopupSheet(this@MainBoardActivity, view, showArrayList, object : PopupSheetCallback {
                override fun setupItemView(position: Int): View {
                    val itemV: View =
                        LayoutInflater.from(this@MainBoardActivity)
                            .inflate(R.layout.item_surgery_name, null)
                    val titleTV = itemV.findViewById<TextView>(R.id.tv_surgery_name)
                    titleTV.text = MessageFormat.format("{0}", showArrayList[position].ruleName)
                    return itemV
                }

                override fun itemClicked(popupWindow: ListPopupWindow, position: Int) {
                    popupWindow.dismiss()
                    view.text = showArrayList[position].ruleName
                    if (showArrayList[position].ruleConfig == null) {
                        setSerValue(tag, showArrayList[position].ruleCode, showArrayList[position].ruleName, "")
                    } else {
                        setSerValue(
                            tag,
                            showArrayList[position].ruleCode,
                            showArrayList[position].ruleName,
                            showArrayList[position].ruleConfig
                        )
                    }
//                    ToastUtils().show(this@MainBoardActivity, "你选择了"+showArrayList[position])
//                    tvShoesSize.text = MessageFormat.format("{0}", "鞋子尺码：$shoesSize")
                }
            }, DimensUtil.dp2px(this@MainBoardActivity, maxWidth+80F))
        popupSheet.show()
    }

    private fun selectSizeDate(view: TextView, arrays: List<SizeConfig>, tag: Int) {
        // 测量文本最大宽度
        var maxWidth = 0f
        var item: String = ""
        // 测量文本最大宽度
        val paint = Paint()
        for (i in 0 until arrays.size) {
            item = arrays.get(i).name
            val width = paint.measureText(item)
            if (width > maxWidth) {
                maxWidth = width
            }
        }
        val popupSheet: PopupSheet
        val showArrayList = arrays//Arrays.asList(/* ...a = */ *arrays)
        popupSheet =
            PopupSheet(this@MainBoardActivity, view, showArrayList, object : PopupSheetCallback {
                override fun setupItemView(position: Int): View {
                    val itemV: View =
                        LayoutInflater.from(this@MainBoardActivity)
                            .inflate(R.layout.item_surgery_name, null)
                    val titleTV = itemV.findViewById<TextView>(R.id.tv_surgery_name)
                    titleTV.text = MessageFormat.format("{0}", showArrayList[position].name)
                    return itemV
                }

                override fun itemClicked(popupWindow: ListPopupWindow, position: Int) {
                    popupWindow.dismiss()
                    view.text = showArrayList[position].name
                    setSerValue(tag, showArrayList[position].code, showArrayList[position].name, "")
//                    ToastUtils().show(this@MainBoardActivity, "你选择了"+showArrayList[position])
//                    tvShoesSize.text = MessageFormat.format("{0}", "鞋子尺码：$shoesSize")
                }
            }, DimensUtil.dp2px(this@MainBoardActivity, maxWidth+80F))
        popupSheet.show()
    }

//    var shoesType: String = "0"
//    var serialType: String = "0"
//    var shoesColor: String = "0"
//    var shoesSize: String = "0"
//    var footType: String = "0"

    private fun setSerValue(p0: Int, code: String, name: String, config: String) {
        val message = Message()
        message.arg1 = 2
        when (p0) {
            0 -> {
                companyCode = code
                companyName = name
                companyConfig = config
                Global.companyCode = companyCode
                Global.companyName = companyName
                Global.companyConfig = companyConfig
            }

            1 -> {
                wordCode = code
                wordName = name
                wordConfig = config
                Global.wordCode = wordCode
                Global.wordName = wordName
                Global.wordConfig = wordConfig
            }

            2 -> {
                shoesCode = code
                shoesName = name
                shoesConfig = config
                if (!Global.shoesName.equals(shoesName)) {
                    sizeCode = ""
                    sizelName = ""
                    sizeConfig = ""
                    Global.sizelName = ""
                    Global.sizeCode = ""
                    Global.sizeConfig = ""

                }
                Global.shoesCode = shoesCode
                Global.shoesName = shoesName
                Global.shoesConfig = shoesConfig

            }

            3 -> {
                serialCode = code
                serialName = name
                serialConfig = config
                Global.serialCode = serialCode
                Global.serialName = serialName
                Global.serialConfig = serialConfig
            }

            4 -> {
                colorCode = code
                colorlName = name
                colorConfig = config
                Global.colorCode = colorCode
                Global.colorlName = colorlName
                Global.colorConfig = colorConfig
            }

            5 -> {
                sizeCode = code
                sizelName = name
                sizeConfig = config
                Global.sizeCode = sizeCode
                Global.sizelName = sizelName
                Global.sizeConfig = sizeConfig
            }

            6 -> {
                specificationCode = code
                specificationName = name
                specificationConfig = config
                Global.specificationCode = specificationCode
                Global.specificationName = specificationName
                Global.specificationConfig = specificationConfig
            }
        }
        handler.sendMessage(message)
    }

    /**
     * 校验产品序列号是否已经存在
     */
    private fun CheckNetIsUse(mac: String, productSn: String) {
        val check = CheckNetUse("", "", "")
        check.mac = mac
        check.productSn = productSn
        check.shortProductSn = serialNumber
        val data = Gson().toJson(check)
        OkHttpUtils.postJsonAsync(this@MainBoardActivity, Api.checkCode, data, object : OkHttpUtils.DataCallBack {
            override fun requestFailure(request: Request, e: IOException) {
                Log.e("MainBoardActivity", "校验产品序列号失败")
//                binding.progressBarWite.visibility = View.GONE
            }

            @Throws(Exception::class)
            override fun requestSuccess(result: String) {
//                binding.progressBarNet.visibility = View.GONE
                val toJsonObj = JSONObject(result)
                Log.e("MainBoardActivity", "校验返回"+toJsonObj)
                val code = toJsonObj.getInt("code")
                if (code == 0) {
                    val message = toJsonObj["message"] as String
                    binding.tvWriteResult.setText("产品序列号校验" + message)
//                    binding.tvNetIsUseResult.text = ""
//                    binding.ivSuccess.visibility = View.VISIBLE
//                    ToastUtils().show(this@MainBoardActivity, "校验" + message)

                    onWriteSerialNumber(productSn)

                } else {
//                    binding.progressBarWite.visibility = View.GONE
                    val message = toJsonObj["message"] as String
//                    binding.tvNetIsUseResult.text = message
                    binding.tvWriteResult.setText(message)
                    ToastUtils().show(this@MainBoardActivity, message)
                }
            }
        })
    }

    /**
     * 保存写码数据(支持修改)
     */
    private fun saveCode(mac: String, productSn: String) {
        val check = CheckNetUse("", "", "")
        check.mac = mac
        check.productSn = productSn
        check.shortProductSn = serialNumber
        val data = Gson().toJson(check)
        OkHttpUtils.postJsonAsync(this@MainBoardActivity, Api.saveCode, data, object : OkHttpUtils.DataCallBack {
            override fun requestFailure(request: Request, e: IOException) {
                Log.e("MainBoardActivity", "上传产品序列号失败")
                binding.tvNextResult.setText("上传序列号，网络请求失败")
//                binding.progressBarSave.visibility = View.GONE
            }

            @Throws(Exception::class)
            override fun requestSuccess(result: String) {
//                binding.progressBarSave.visibility = View.GONE
//                binding.progressBarWite.visibility = View.GONE
                val toJsonObj = JSONObject(result)
                Log.e("MainBoardActivity", "校验返回"+toJsonObj)
                val code = toJsonObj.getInt("code")
                if (code == 0) {
                    binding.tvNextResult.setText("序列号上传成功")
//                    binding.ivWriteSuccess.visibility = View.VISIBLE
                    val message = toJsonObj["message"] as String
                    ToastUtils().show(this@MainBoardActivity, "产品序列号上传" + message)
                    manager.addToBlacklist(mac)//加入黑名单
                    disConnect()
                    bluetoothController.startScanBle()
                } else {
                    val message = toJsonObj["message"] as String
                    binding.tvNextResult.text = message
                    ToastUtils().show(this@MainBoardActivity, message)
                }
            }
        })
    }


    private fun disConnect() {
        reSetValue()
        Global.addressCheck = ""
        Global.address = null
        foundDevices.clear()
        deviceList.clear()
        adapter.submitList(emptyList())
        if (BluetoothController.macAddress != null) {
            bluetoothController.closeBuletooth(BluetoothController.macAddress)
        }
        bluetoothController.stopScanBle()
    }

    private fun reSetValue() {
        runOnUiThread {
//            binding.tvSerialNumber.text = ""
            serialNumber = ""
            binding.tvWriteSerialNumberResult.text = companyCode+shoesCode+wordCode+serialCode+specificationCode+Global.footCode+sizeCode+colorCode+Global.colorConfig+serialNumber
            binding.ivSuccess.visibility = View.GONE
            binding.ivSaveSuccess.visibility = View.GONE
            binding.ivPutinSuccess.visibility = View.GONE
//            binding.tvWriteFootType.text = "选择左右脚"
            binding.tvWriteResult.text = ""
            binding.tvNextResult.text = ""
            binding.tvPutinComparisonResult.text = ""
            binding.tvSaveResult.text = ""
            binding.btnScanCode.setBackgroundResource(R.drawable.bg_grey_btn)
            binding.btnScanCode.isEnabled = false
            binding.btnWrite.setBackgroundResource(R.drawable.bg_grey_btn)
            binding.btnWrite.isEnabled = false
//            binding.tvWriteFootType.setBackgroundResource(R.drawable.bg_grey_btn)
//            binding.tvWriteFootType.isEnabled = false
            binding.btnPutInComparison.setBackgroundResource(R.drawable.bg_grey_btn)
            binding.btnPutInComparison.isEnabled = false
            binding.btnSave.setBackgroundResource(R.drawable.bg_grey_btn)
            binding.btnSave.isEnabled = false
            binding.btnNext.setBackgroundResource(R.drawable.bg_grey_btn)
            binding.btnNext.isEnabled = false
        }

    }

    private fun checkDate(): Boolean{
        if (BluetoothController.macAddress == null) {
            ToastUtils().show(this@MainBoardActivity, "请先连接蓝牙鞋")
            return false
        }
        if (companyName.equals("")) {
            ToastUtils().show(this@MainBoardActivity, "请选择公司")
            return false
        }
        if (wordName.equals("")) {
            ToastUtils().show(this@MainBoardActivity, "请核心词")
            return false
        }
        if (shoesName.equals("")) {
            ToastUtils().show(this@MainBoardActivity, "请选择产品")
            return false
        }
        if (serialName.equals("")) {
            ToastUtils().show(this@MainBoardActivity, "请选择款式")
            return false
        }
        if (colorlName.equals("")) {
            ToastUtils().show(this@MainBoardActivity, "请选择颜色")
            return false
        }
        if (sizelName.equals("")) {
            ToastUtils().show(this@MainBoardActivity, "请选择尺码")
            return false
        }
        if (specificationName.equals("")) {
            ToastUtils().show(this@MainBoardActivity, "请选择规格")
            return false
        }
//        if (Global.footName.equals("")) {
//            ToastUtils().show(this@MainBoardActivity, "请选择左右脚")
//            return false
//        }
        if (binding.tvPutinComparisonResult.text.toString().equals("")) {
            ToastUtils().show(this@MainBoardActivity, "请先扫码获取鞋垫序列号")
            return false
        }
        return true
    }

    private fun isnetUsed() {
//        binding.progressBarWite.visibility = View.VISIBLE
//        binding.tvNetIsUseResult.text = ""
        binding.tvWriteResult.setText("正在校验产品序列号...")
        CheckNetIsUse(
            BluetoothController.macAddress,
            binding.tvWriteSerialNumberResult.text.toString()
        )
    }

    private fun checkWrite() {
//        binding.tvPutinComparisonResult.text = ""
//        if (!checkDate()) {
//            return
//        }
        Global.addressCheck = BluetoothController.macAddress
        Global.address = null
        foundDevices.clear()
        deviceList.clear()
        adapter.submitList(emptyList())
        if (BluetoothController.macAddress != null) {
            bluetoothController.closeBuletooth(BluetoothController.macAddress)
        }
        bluetoothController.startScanBle()
    }

    private fun saveDate() {
//        if (!checkDate()) {
//            return
//        }
        binding.tvNextResult.text = "正在上传序列号..."
//        binding.progressBarSave.visibility = View.VISIBLE
        saveCode(
            BluetoothController.macAddress,
            binding.tvWriteSerialNumberResult.text.toString()
        )
    }

    private fun WriteSN() {
        isnetUsed()
    }

    var shoeSex: Int = -1//鞋性别
    //公司
    var companyCode: String = ""//ZH和XZ
    var companyName: String = ""
    var companyConfig: String = ""
    //训练仪
    var wordCode: String = ""//ZH和XZ
    var wordName: String = ""
    var wordConfig: String = ""
    //特征词
    var shoesCode: String = ""//ZH和XZ
    var shoesName: String = ""
    var shoesConfig: String = ""
    //款型
    var serialCode: String = ""
    var serialName: String = ""
    var serialConfig: String = ""
    //颜色
    var colorCode: String = ""
    var colorlName: String = ""
    var colorConfig: String = ""
    //大小
    var sizeCode: String = ""
    var sizelName: String = ""
    var sizeConfig: String = ""
    //规格代码
    var specificationCode: String = ""
    var specificationName: String = ""
    var specificationConfig: String = ""

    var foot: String = ""
    var productSnPrefix: String =""
    private fun getDate() {

        // 接收基本数据类型
        companyCode = intent.getStringExtra("companyCode").toString()
        companyName = intent.getStringExtra("companyName").toString()
        companyConfig = intent.getStringExtra("companyConfig").toString()

        wordCode = intent.getStringExtra("wordCode").toString()
        wordName = intent.getStringExtra("wordName").toString()
        shoesConfig = intent.getStringExtra("shoesConfig").toString()

        shoesCode = intent.getStringExtra("shoesCode").toString()
        shoesName = intent.getStringExtra("shoesName").toString()
        shoesConfig = intent.getStringExtra("shoesConfig").toString()

        serialCode = intent.getStringExtra("serialCode").toString()
        serialName = intent.getStringExtra("serialName").toString()
        serialConfig = intent.getStringExtra("serialConfig").toString()

        colorCode = intent.getStringExtra("colorCode").toString()
        colorlName = intent.getStringExtra("colorlName").toString()
        colorConfig = intent.getStringExtra("colorConfig").toString()

        sizeCode = intent.getStringExtra("sizeCode").toString()
        sizelName = intent.getStringExtra("sizelName").toString()
        sizeConfig = intent.getStringExtra("sizeConfig").toString()

        specificationCode = intent.getStringExtra("specificationCode").toString()
        specificationName = intent.getStringExtra("specificationName").toString()
        specificationConfig = intent.getStringExtra("specificationConfig").toString()
        // 保存产品序列号前缀  用于校验
        productSnPrefix = companyCode+shoesCode+wordCode+serialCode+specificationCode+sizeCode+colorCode+Global.colorConfig


//        footType = intent.getStringExtra("footType").toString()
//        if (Global.footName.equals("左脚")) {
//            binding.tvWriteFootTypeLeft.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))
//            binding.tvWriteFootTypeLeft.setBackgroundResource(R.drawable.bg_orange_btn)
//
//            binding.tvWriteFootTypeRight.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.black))
//            binding.tvWriteFootTypeRight.setBackgroundResource(R.drawable.bg_black_frame_btn)
//        } else if (Global.footName.equals("右脚")) {
//            binding.tvWriteFootTypeLeft.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.black))
//            binding.tvWriteFootTypeLeft.setBackgroundResource(R.drawable.bg_black_frame_btn)
//
//            binding.tvWriteFootTypeRight.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.white))
//            binding.tvWriteFootTypeRight.setBackgroundResource(R.drawable.bg_orange_btn)
//        }

        setConfigDate(0)  //  0 代表  刚进去  无法知道选择左脚还是右脚 不显示类型    1  代表已经连接可以知晓左右脚

    }

    private fun setConfigDate(type :Int) {
        runOnUiThread {
            binding.tvWriteCompanyValue.text = companyName
            binding.tvWriteWordValue.text = wordName
            binding.tvWriteShoesTypeValue.text = shoesName
            binding.tvWriteSerialTypeValue.text = serialName
            binding.tvWriteShoesColorValue.text = colorlName
            binding.tvWriteShoesSizeValue.text = sizelName
            binding.tvWriteSpecificationValue.text = specificationName

            if (type == 0) {

                binding.tvWriteSerialNumberResult.text =
                    companyCode + shoesCode + wordCode + serialCode + specificationCode +  sizeCode + colorCode + Global.colorConfig + serialNumber
            } else if (type == 1) {

                binding.tvWriteSerialNumberResult.text =
                    companyCode + shoesCode + wordCode + serialCode + specificationCode + Global.footCode + sizeCode + colorCode + Global.colorConfig + serialNumber
            }
        }
    }

    private fun getItems(code: String): MutableList<DictItem> {
        var dictList = mutableListOf<DictItem>()
        try {
            parseDictList(Global.dictConfig).forEach { dictData ->
                println("字典类型: ${dictData.dictName}")
                if (code.equals(dictData.dictCode)) {
                    val items: MutableList<DictItem> = dictData.items
                    dictList = items
                    return items
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return dictList
    }

    private fun parseDictList(json: String): List<DictData> {
        return Gson().fromJson(json, object : TypeToken<List<DictData>>() {}.type)
    }

    private fun reSetFootType() {
        binding.tvWriteFootTypeLeft.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.black))
        binding.tvWriteFootTypeLeft.setBackgroundResource(R.drawable.bg_black_frame_btn)

        binding.tvWriteFootTypeRight.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.black))
        binding.tvWriteFootTypeRight.setBackgroundResource(R.drawable.bg_black_frame_btn)
    }

    private fun reSetRissbg(riss: String) {
        binding.tvBoardRssiIdFour.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.black))
        binding.tvBoardRssiIdFour.setBackgroundResource(R.drawable.bg_black_frame_btn)

        binding.tvBoardRssiIdFive.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.black))
        binding.tvBoardRssiIdFive.setBackgroundResource(R.drawable.bg_black_frame_btn)

        binding.tvBoardRssiIdSix.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.black))
        binding.tvBoardRssiIdSix.setBackgroundResource(R.drawable.bg_black_frame_btn)

        binding.tvBoardRssiIdSeven.setTextColor(ContextCompat.getColor(this@MainBoardActivity, R.color.black))
        binding.tvBoardRssiIdSeven.setBackgroundResource(R.drawable.bg_black_frame_btn)

        when (riss) {
            "-40" -> {
                currentRssiThreshold = -40
            }

            "-50" -> {
                currentRssiThreshold = -50
            }

            "-60" -> {
                currentRssiThreshold = -60
            }
            "-70" -> {
                currentRssiThreshold = -70
            }
        }
//        foundDevices.clear()
//        deviceList.clear()
////        adapter.submitList(emptyList())
//        if (BluetoothController.macAddress != null){
//            foundDevices.add(connectDevice)
//        }
//        adapter.submitList(foundDevices.toList())
//        bluetoothController.startScanBle()
    }

    private fun setUserConfig(
        company: String,
        featureWords: String,
        coreWords: String,
        modelCode: String,
        specificationCode: String,
        footType: String,
        color: String,
        shoeSize: String,
        mobileCode: String
    ) {
        val user = UserConfigBean()
        user.company = company
        user.featureWords = featureWords
        user.coreWords = coreWords
        user.modelCode = modelCode
        user.specificationCode = specificationCode
        user.footType = footType
        user.color = color
        user.shoeSize = shoeSize
        user.mobileCode = mobileCode
        val data = Gson().toJson(user)
        OkHttpUtils.postJsonAsync(
            this@MainBoardActivity,
            Api.updateConfig,
            data,
            object : OkHttpUtils.DataCallBack {
                override fun requestFailure(request: Request, e: IOException) {
                }

                @Throws(java.lang.Exception::class)
                override fun requestSuccess(result: String) {
                    val toJsonObj = JSONObject(result)
                    val code = toJsonObj.getInt("code")
                    if (code == 0) {
                    } else {
                        val message = toJsonObj["message"] as String
                        ToastUtils().show(this@MainBoardActivity, message)
                    }
                }
            })
    }

    var bindCount: Int = 5

    private fun bindShoes(
        mac: String,
        shoeSn: String,
    ) {
        val shoes = BindShoes()
        shoes.mac = mac
        shoes.shoeSn = shoeSn
        val data = Gson().toJson(shoes)
        OkHttpUtils.postJsonAsync(
            this@MainBoardActivity,
            Api.bindShoes,
            data,
            object : OkHttpUtils.DataCallBack {
                override fun requestFailure(request: Request, e: IOException) {
                    Log.e("BindActivity", "保存失败")
                    if (bindCount >= 0) {
                        bindCount--
                        bindShoes(mac, shoeSn)
                    } else {
//                        binding.progressBarWite.visibility = View.GONE
                        ToastUtils().show(this@MainBoardActivity, "保存失败，请检查网络重试")
                    }
                }

                @Throws(Exception::class)
                override fun requestSuccess(result: String) {
//                    binding.pbLoadingBindSave.visibility = View.GONE
                    bindCount = 5
                    val toJsonObj = JSONObject(result)
                    Log.e("BindActivity", "上传返回" + toJsonObj)
                    val code = toJsonObj.getInt("code")
                    if (code == 0) {
                          saveDate()//自动保存当前序列号
//                        isnetUsed()//绑定成功后，开始写码
//                        manager.addToBlacklist(mac)
//                        disConnected()
//                        bluetoothController.startScanBle()
//                        val message = toJsonObj["message"] as String
//                        ToastUtils().show(this@BindActivity, "保存" + message)
                    } else {
                        val message = toJsonObj["message"] as String
                        ToastUtils().show(this@MainBoardActivity, message)
                    }
                }
            })

    }


    /**
     * 蓝牙状态广播回调
     */
    internal class BtTemperatureReceiver : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val action = intent.action
            //注意!这里是先拿action 等于 BluetoothAdapter.ACTION_STATE_CHANGED 在解析intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0)
            if (BluetoothAdapter.ACTION_STATE_CHANGED == Objects.requireNonNull<String?>(action)) {
                val blState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0)
                when (blState) {
                    BluetoothAdapter.STATE_TURNING_ON -> {
                    }
                    BluetoothAdapter.STATE_ON ->
//                        ToastUtils.show(ConnectDeviceActivity.this, "蓝牙开启成功");
//                        Toast.makeText(ConnectDeviceActivity.this,"蓝牙开启成功",Toast.LENGTH_SHORT).show();
                    {
                        BluetoothController.getInstance().startScanBle()
                    }

                    BluetoothAdapter.STATE_TURNING_OFF -> //                        ToastUtils.show(ConnectDeviceActivity.this, "蓝牙正在关闭中……，请稍等");
//                        Toast.makeText(ConnectDeviceActivity.this,"蓝牙正在关闭中……，请稍等",Toast.LENGTH_SHORT).show();

                    {

                    }
                    BluetoothAdapter.STATE_OFF -> {
                        //                        ToastUtils.show(ConnectDeviceActivity.this, "蓝牙已关闭");
//                        Toast.makeText(ConnectDeviceActivity.this,"蓝牙已关闭",Toast.LENGTH_SHORT).show();
                    }

                    BluetoothAdapter.ERROR -> {

                    }

                    else -> {}
                }
            }
        }
    }


    /**
     * 移除超时未出现的设备（蓝牙已关机）
     */
    private fun removeTimeoutDevices() {
        val currentTime = System.currentTimeMillis()
        var needUpdate = false

        // 直接遍历 foundDevices 来检查超时
        val iterator = foundDevices.iterator()
        while (iterator.hasNext()) {
            val device = iterator.next()

            // 跳过当前连接的设备
            if (device.address == BluetoothController.macAddress) {
                continue
            }

            val lastSeen = deviceTimeoutMap[device.address]

            // 如果设备超过超时时间没有出现，认为已离线
            if (lastSeen == null || currentTime - lastSeen > DEVICE_TIMEOUT) {
                iterator.remove()
                deviceTimeoutMap.remove(device.address)

                // 同时从 deviceList 中移除（如果存在）
                val deviceListIterator = deviceList.iterator()
                while (deviceListIterator.hasNext()) {
                    if (deviceListIterator.next().device.address == device.address) {
                        deviceListIterator.remove()
                        break
                    }
                }

                needUpdate = true
                Log.d(TAG, "设备离线移除: ${device.name} - ${device.address}")
            }
        }

        if (needUpdate) {
            updateDeviceListDisplay()
        }
    }

    /**
     * 更新设备列表显示
     */
    private fun updateDeviceListDisplay() {
        // 按RSSI排序
        foundDevices.sortByDescending { it.rssi }
        adapter.submitList(foundDevices.toList())
    }

}